using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using OpenPasteSpider.bind;
using PasteFormHelper;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories;

namespace OpenPasteSpider.projectmodel
{

    /// <summary>
    /// 模块
    ///</summary>
    [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "view" })]
    public class ModelInfoAppService : OpenPasteSpiderAppService
    {

        private IOpenPasteSpiderDbContext _dbContext;
        private readonly PublicModelHelper _modelHelper;
        public ModelInfoAppService(IOpenPasteSpiderDbContext dbContext, PublicModelHelper modelHelper)
        {
            _dbContext = dbContext;
            _modelHelper = modelHelper;
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PagedResultDto<ModelInfoListDto>> GetListAsync(InputSearchApp input)
        {

            var query = _dbContext.ModelInfo.Where(t => 1 == 1)
                .WhereIf(input.projectid != 0, x => x.ProjectId == input.projectid)
                .WhereIf(!string.IsNullOrEmpty(input.word), x => x.Service.Name.Contains(input.word))
                .Include(x => x.Service)
                .Include(x => x.Service.Project)
                .OrderByDescending(xy => xy.Id);

            var pagedResultDto = new PagedResultDto<ModelInfoListDto>();
            pagedResultDto.TotalCount = await query.CountAsync();
            var userList = await query.Page(input.page, input.size).ToListAsync();
            var temList = ObjectMapper.Map<List<ModelInfo>, List<ModelInfoListDto>>(userList);
            pagedResultDto.Items = temList;
            return pagedResultDto;
        }

        /// <summary>
        /// 用于升级选择对象 CS端读取使用
        /// </summary>
        /// <param name="serviceid"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<dynamic> SearchForUpdate(int serviceid)
        {

            //var _query = await _dbContext.BindModelLinux.Where(x => x.ServiceId == serviceid && x.IsEnable).AsNoTracking().ToListAsync();

            //if (_query != null && _query.Count > 0)
            //{
            //    return ObjectMapper.Map<List<BindModelLinux>, List<BindModelLinuxDto>>(_query);
            //}
            //else
            //{
            //    throw new PasteException("当前服务没有可用的环境信息，无法查询到数据！环境需要配置分布才能算是有效的配置！");
            //}

            var query = from a in _dbContext.BindModelLinux.Where(x => x.ServiceId == serviceid && x.IsEnable)
                        join b in _dbContext.ModelInfo on a.ModelId equals b.Id into c
                        from d in c.DefaultIfEmpty()
                        join e in _dbContext.LinuxInfo on a.LinuxId equals e.Id into f
                        from g in f.DefaultIfEmpty()
                        select new
                        {
                            modelid = a.Id,
                            modelcode = d != null ? d.Code : "",
                            linuxid = a.LinuxId,
                            linuxname = g != null ? g.Name : ""
                        };

            var list = await query.ToListAsync();
            if(list!=null && list.Count > 0)
            {
                return list;
            }
            else
            {
                throw new PasteCodeException("没有查询到这个服务对应的环境信息，请先配置环境信息并设置分布信息后再试!");
            }

        }



        /// <summary>
        /// 根据ID获取单项模块
        ///</summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public ModelInfoDto GetByIdAsync(int id)
        {
            var query = _dbContext.ModelInfo.Where(t => t.Id == id).Include(x => x.Service).FirstOrDefault();
            var temList = ObjectMapper.Map<ModelInfo, ModelInfoDto>(query);
            return temList;
        }

        /// <summary>
        /// 根据ID获取待更新单项信息模块
        ///</summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public ModelInfoUpdateDto GetInfoForUpdateAsync(int id)
        {
            var query = _dbContext.ModelInfo.Where(t => t.Id == id).Include(x => x.Service).FirstOrDefault();
            var temList = ObjectMapper.Map<ModelInfo, ModelInfoUpdateDto>(query);
            temList.ServiceId = query.Service.Id; return temList;
        }


        /// <summary>
        /// 添加一个模块
        ///</summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ModelInfoDto> CreateItemAsync(ModelInfoAddDto input)
        {

            var newu = ObjectMapper.Map<ModelInfoAddDto, ModelInfo>(input);
            if (input.ServiceId != 0)
            {
                var _mtypeservice = await _dbContext.ServiceInfo.Where(x => x.Id == input.ServiceId).Include(x => x.Project).FirstOrDefaultAsync();
                if (_mtypeservice == null || _mtypeservice == default)
                {
                    throw new UserFriendlyException("类型不存在，请确认!");
                }
                newu.Service = _mtypeservice;
                newu.ProjectId = _mtypeservice.Project.Id;

            }            //添加自定义
            _dbContext.Add(newu);

            _dbContext.Database.BeginTransaction();
            try
            {
                _dbContext.Add(newu);
                await _dbContext.SaveChangesAsync();

                if (input.linuxs != null && input.linuxs.Length > 0)
                {
                    foreach (var ii in input.linuxs)
                    {
                        //创建默认模型
                        var _model = new BindModelLinux()
                        {
                            IsEnable = true,
                            LimitMaxNum = 10,
                            LimitMinNum = 1,
                            LinuxId = ii,
                            ModelCode = input.Code,
                            ModelId = newu.Id,
                            ServiceId = input.ServiceId,
                            Weight = 100
                        };
                        _dbContext.Add(_model);
                    }
                }


                await _dbContext.SaveChangesAsync();
                _dbContext.Database.CommitTransaction();
            }
            catch (Exception exl)
            {
                _dbContext.Database.RollbackTransaction();
                throw new PasteCodeException(exl.Message);
            }

            //await _dbContext.SaveChangesAsync();
            //var updated = await _repository.InsertAsync(newu,true);
            var backinfo = ObjectMapper.Map<ModelInfo, ModelInfoDto>(newu);
            return backinfo;
        }

        /// <summary>
        /// 更新一个模块
        ///</summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ModelInfoDto> UpdateItemAsync(ModelInfoUpdateDto input)
        {
            var info = await _dbContext.ModelInfo.Where(x => x.Id == input.Id).Include(x => x.Service).FirstOrDefaultAsync();
            if (info == null || info == default)
            {
                throw new UserFriendlyException("需要查询的信息不存在", "404");
            }
            ObjectMapper.Map<ModelInfoUpdateDto, ModelInfo>(input, info);
            if (input.ServiceId != 0)
            {
                if (info.Service == null || input.ServiceId != info.Service.Id)
                {
                    var _mtypeservice = await _dbContext.ServiceInfo.Where(x => x.Id == input.ServiceId).Include(x => x.Project).FirstOrDefaultAsync();
                    if (_mtypeservice == null || _mtypeservice == default)
                    {
                        throw new UserFriendlyException("类型不存在，请确认!");
                    }
                    info.Service = _mtypeservice;
                    info.ProjectId = _mtypeservice.Project.Id;
                }
            }            //var updated = await _repository.UpdateAsync(newu);
            await _dbContext.SaveChangesAsync();
            var backinfo = ObjectMapper.Map<ModelInfo, ModelInfoDto>(info);
            await _modelHelper.ItemModelCleanAsync(input.Id);
            return backinfo;
        }
        
        /// <summary>
        /// 读取AddDto的数据模型 用于新增
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "view" })]
        public VoloModelInfo ReadAddModel()
        {
            var _model = PasteBuilderHelper.ReadModelProperty<ModelInfoAddDto>(new ModelInfoAddDto());
            return _model;
        }

        /// <summary>
        /// 读取Dto的数据模型 用于更新
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "view" })]
        public async Task<VoloModelInfo> ReadUpdateModel(int id)
        {
            var _info = await _dbContext.ModelInfo.Where(x => x.Id == id).AsNoTracking().FirstOrDefaultAsync();
            if (_info == null || _info == default)
            {
                throw new PasteCodeException("查询的信息不存在，无法执行编辑操作！");
            }
            var dto = ObjectMapper.Map<ModelInfo, ModelInfoUpdateDto>(_info);
            var _dataModel = PasteBuilderHelper.ReadModelProperty<ModelInfoUpdateDto>(dto);
            return _dataModel;
        }

        /// <summary>
        /// 读取Dto的数据模型 用于查看详情
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "view" })]
        public async Task<VoloModelInfo> ReadDetailModel(int id)
        {
            var _info = await _dbContext.ModelInfo.Where(x => x.Id == id).AsNoTracking().FirstOrDefaultAsync();
            if (_info == null || _info == default)
            {
                throw new PasteCodeException("查询的信息不存在，无法执行编辑操作！");
            }
            var dto = ObjectMapper.Map<ModelInfo, ModelInfoDto>(_info);
            var _dataModel = PasteBuilderHelper.ReadModelProperty<ModelInfoDto>(dto);
            return _dataModel;
        }

        /// <summary>
        /// 读取ListDto的数据模型
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "view" })]
        public VoloModelInfo ReadListModel()
        {
            var _model = PasteBuilderHelper.ReadModelProperty<ModelInfoListDto>(new ModelInfoListDto());
            var _query_model = PasteBuilderHelper.ReadModelProperty(new InputSearchBase());
            if (_query_model != null)
            {
                _model.QueryProperties = _query_model.Properties;
            }
            return _model;
        }

        /// <summary>
        /// 按页获取数据
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpGet]
        [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "view" })]
        public async Task<PagedResultDto<ModelInfoListDto>> Page([FromQuery]InputSearchBase input)
        {
            var query = _dbContext.ModelInfo.Where(t => 1 == 1).OrderByDescending(x=>x.Id);
            var _pagedto = new PagedResultDto<ModelInfoListDto>();
            _pagedto.TotalCount = await query.CountAsync();
            var userList = await query.Page(input.page, input.size).ToListAsync();
            var temList = ObjectMapper.Map<List<ModelInfo>, List<ModelInfoListDto>>(userList);
            _pagedto.Items = temList;
            return _pagedto;
        }    }
}
